package core.pool;

import java.util.concurrent.LinkedBlockingQueue;

public class BoundedPool<T extends AutoCloseable> implements iPool<T> {

    private int size;
    private LinkedBlockingQueue< T> objects;
    private iResourceFactory< T> objectFactory;
    private volatile boolean isShutdown;

    public BoundedPool(int size, iResourceFactory< T> objectFactory) {
        super();
        this.objectFactory = objectFactory;
        this.size = size;
        objects = new LinkedBlockingQueue<>(size);
        initializeObjects();
        isShutdown = false;
    }

    @Override
    public T get() {
        T t = null;
        if (!isShutdown) {
            t = objects.poll();
        } else {
            throw new IllegalStateException("Object pool already shutdown");
        }
        return t;
    }

    @Override
    public void shutdown() {
        isShutdown = true;
        clearResources();
    }

    private void clearResources() {
        for (T t : objects) {
            try {
                t.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void putInPool(T t) {
        objects.add(t);
    }

    private void initializeObjects() {
        for (int i = 0; i < size; i++) {
            objects.add(objectFactory.create());
        }
    }
}
